package com.eastedu.report.principal.util;

import com.deepoove.poi.data.RenderData;
import com.deepoove.poi.data.SeriesRenderData;
import com.eastedu.report.principal.model.PeriodAndSubjectReportData;
import com.eastedu.template.chart.ChartMetadata;
import com.eastedu.template.model.ChartData;
import com.eastedu.template.model.SeriesData;
import com.eastedu.template.util.ChartDataUtil;
import com.eastedu.utils.CollectionUtils;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 校长月报报告图表工具
 *
 * @author superman
 */
public interface ReportChartUtil {

    /**
     * 基于学届和学科的报告图表，并且包含总体数据
     * <p>
     * 注意：
     * * 该函数目前只在‘同步教学’、‘同步教研’数据图表中使用，如果后续有其他相似数据图表需要使用该函数，请自行测试
     * * 如果需要修改该函数，请通知其他使用该函数的同事
     *
     * @param <T>          the type parameter
     * @param title        the title
     * @param categories   the categories
     * @param series       the series
     * @param data         the data
     * @param dataFunction the data function
     * @return the render data
     */
    static <T extends PeriodAndSubjectReportData> RenderData chart(String title,
                                                                   List<ChartMetadata> categories,
                                                                   List<ChartMetadata> series,
                                                                   List<T> data,
                                                                   java.util.function.Function<T, Number> dataFunction) {
        Map<String, Map<String, T>> groups = data.stream().collect(Collectors.groupingBy(t1 -> {
            if (Objects.isNull(t1.getSchoolPeriod())) {
                return "";
            }
            return t1.getSchoolPeriod();
        }, Collectors.toMap(T::getSubjectCode, d -> d)));

        // 构建图表数据
        List<SeriesData> seriesDataList = ChartDataUtil.charFunction(dataFunction).apply(categories, series, groups);

        // 构建总体数据
        Number[] total = new Number[categories.size()];
        if (!CollectionUtils.isEmpty(data)) {
            Map<String, T> totalGroup = groups.get("");
            if (!CollectionUtils.isEmpty(totalGroup)) {
                for (int i = 0; i < categories.size(); i++) {
                    ChartMetadata category = categories.get(i);
                    T t = totalGroup.get(category.getCode());
                    if (t != null) {
                        total[i] = dataFunction.apply(t);
                    }
                }
            }
        }

        seriesDataList.add(new SeriesData("总体", 1, total, SeriesRenderData.ComboType.LINE));
        return ChartDataUtil.convertChartData(new ChartData(title, categories.stream().map(ChartMetadata::getName).toArray(String[]::new), seriesDataList));
    }
}
